package se19team1e.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import se19team1e.dao.abstrakt.jaas.CompanyDAO;
import se19team1e.dao.abstrakt.jaas.DepartmentDAO;
import se19team1e.dao.abstrakt.jaas.JobAdvertDAO;
import se19team1e.dao.factory.DAOFactory;
import se19team1e.dao.factory.DAOFactorySelector;
import se19team1e.entity.CompanyDTO;
import se19team1e.entity.DepartmentDTO;
import se19team1e.entity.JobAdvertDTO;
import se19team1e.exception.DataAccessException;
import se19team1e.gui.DeleteJobAdvertForm;
import se19team1e.gui.JobAdvertSearchForm;
import se19team1e.search.SearchEngine;
import se19team1e.search.SearchEngineFactory;
import se19team1e.util.StringUtil;

/**
 * 
 * The delete job advert controller class coordinates the operations between the screen, form, and entity objects for deleting job advert.
 * 
 * @author Toh Chen Lim
 *
 */
public class DeleteJobAdvertController extends BaseController {

    /**
     * Constructs the controller.
     * 
     * @param application Reference to the current application instance.
     */
    public DeleteJobAdvertController( Application application ) {
        super( application );
    }

    /**
     * Initializes the controller.
     * 
     * <p>
     * The delete job advert form is initialized and set as the current active screen.
     * </p>
     * <p>
     * Initialization involves the retrieval of all companies and departments in the system.
     * </p>
     * 
     * @throws DataAccessException 
     */
    public void initialize(JobAdvertDTO jobAdvertDTO) throws DataAccessException {
        DAOFactory daoFactory = DAOFactorySelector.getDAOFactory();

        // get all companies
        CompanyDAO companyDAO = daoFactory.getCompanyDAO();
        List<CompanyDTO> companies = companyDAO.retrieveAll();
        
        // get all departments
        DepartmentDAO departmentDAO = daoFactory.getDepartmentDAO();
        List<DepartmentDTO> departments = departmentDAO.retrieveAll();
        
        // get screen
        DeleteJobAdvertForm screen = this.getApplication().getScreen( DeleteJobAdvertForm.class );


        if (!StringUtil.isEmptyOrNull(jobAdvertDTO.getDepartmentId())){
        	DepartmentDTO departmentDTO= departmentDAO.retrieveById(jobAdvertDTO.getDepartmentId());
        	jobAdvertDTO.setDepartmentName(departmentDTO.getName());
        }
        
        if (!StringUtil.isEmptyOrNull(jobAdvertDTO.getCompanyId())){
        	CompanyDTO companyDTO= companyDAO.retrieveById(jobAdvertDTO.getCompanyId());
        	jobAdvertDTO.setCompanyName(companyDTO.getName());
        }
        // initialize screen
        screen.initialize(jobAdvertDTO, this, companies, departments );
        
        // set as active screen (if job advert is not of 'deleted' status)
        if (validateNotDeleted(jobAdvertDTO)) {
            this.getApplication().setCurrentScreen( screen );
        }
    }

    /**
     * Check to make sure the Job Advert is not of 'deleted' status 
     * and deletes it from persistence storage.
     * 
     * @param jobAdvert Job Advert to delete.
     * @throws DataAccessException 
     */
    public void deleteJobAdvert( JobAdvertDTO jobAdvert ) throws DataAccessException {
        // check to ensure job advert is not of 'deleted' status first
    	if (!validateNotDeleted(jobAdvert)) {
            // job advert is of 'deleted' status, return
            return;
        }
        
        JobAdvertDAO jobAdvertDAO = DAOFactorySelector.getDAOFactory().getJobAdvertDAO();
        jobAdvertDAO.delete(jobAdvert.getId());

        removeJobAdvertFromSearchEngine( jobAdvert );
        
        // display success message
        this.displayDeleteSuccessMessage();
    }

    /**
     * Shows the search job advert form.
     * 
     * <p>
     * This time, only the form is set as the active screen, and no furthur initialization is asked to be done.
     * </p>
     * <p>
     * This is called after user clicks on "Ok" on the notification dialog box.
     * </p>
     */
    public void showJobAdvertSearchForm() {
        // get screen
        JobAdvertSearchForm screen = this.getApplication().getScreen(JobAdvertSearchForm.class); 
        // no need to reinitialize, reuse same content.
        
        // set as active screen
        this.getApplication().setCurrentScreen( screen );
    }


    /**
     * Deletes the job advert from the persistence storage.
     * 
     * <p>
     * This method is set to package level access for unit testing purpose.
     * </p>
     * @param jobAdvert Job Advert to delete.
     * @throws DataAccessException 
     */
    void saveJobAdvert( JobAdvertDTO jobAdvert ) throws DataAccessException {
        DAOFactory daoFactory = DAOFactorySelector.getDAOFactory();
        
        // deletes the job advert
        JobAdvertDAO jobAdvertDAO = daoFactory.getJobAdvertDAO();
        jobAdvertDAO.delete( jobAdvert );
    }

    /**
     * Remove the job advert from the search engine.
     * 
     * <p>
     * This method is set to package level access for unit testing purpose.
     * </p>
     * @param jobAdvert Job Advert to remove from search engine.
     */
    void removeJobAdvertFromSearchEngine( JobAdvertDTO jobAdvert ) {
    	SearchEngine searchEngine = getApplication().getSearchEngine();
        searchEngine.removeFromIndex( jobAdvert );
    }

    /**
     * Displays a message box indicating that creation is success
     */
    private void displayDeleteSuccessMessage() {
        this.displayMessage( "Success", "Job Advert Successfully Deleted.", new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
               // show the input screen again
                getApplication().selectSearchJobAdvert();
            }
        });
    }

    /**
     * Displays a message box indicating that input is missing.
     */
    protected void displayMissingInputErrorMessage( String field ) {
        this.displayMessage( "Error", "Missing " + field, new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
               // do nothing
            }
        });
    }

    /**
     * Shows the search job advert results screen again.
     * 
     * <p>
     * This time, only the screen is set as the active screen, and no furthur initialization is asked to be done.
     * </p>
     * <p>
     * This is to retain the previous search results.
     * </p>
     */
    public void showSearchJobAdvertResultsScreen() {
        // get screen
        JobAdvertSearchForm screen = this.getApplication().getScreen( JobAdvertSearchForm.class );
        
        // no need to reinitialize, reuse same content.
        
        // set as active screen
        this.getApplication().setCurrentScreen( screen );
    }

    /**
     * Validates if the job advert is not deleted.
     * 
     * @param jobAdvert Job advert to validate.
     * @return True if valid.
     */
    private boolean validateNotDeleted( JobAdvertDTO jobAdvert ) {
        if ( jobAdvert.isDeleted() ) {
            // failure, display error message
            this.displayMessage( "Error", "Job Advert already deleted", new ActionListener() {
                @Override
                public void actionPerformed( ActionEvent event ) {
                   // do nothing
                }
            });
            
            return false; 
        }
        return true;
    }

}
